import { boot } from 'quasar/wrappers';
import axios, { AxiosInstance } from 'axios';
import { Notify } from 'quasar';
import { router } from 'src/router';
import { Message } from 'app/typings';
import { useStore } from 'src/status';

declare module '@vue/runtime-core' {
  interface ComponentCustomProperties {
    $axios: AxiosInstance;
  }
}

// Be careful when using SSR for cross-request state pollution
// due to creating a Singleton instance here;
// If any client changes this (global) instance, it might be a
// good idea to move this instance creation inside of the
// "export default () => {}" function below (which runs individually
// for each client)
const api = axios.create({
  baseURL: '/api',
  timeout: 5000,
  withCredentials: true,
});
api.interceptors.response.use(
  (value) => {
    if (
      !router.currentRoute.value.path.includes('/auth') &&
      (value.data as Message).code === 1018
    ) {
      Notify.create({
        message: '登陆状态过期，请重新登陆！',
        position: 'top',
        type: 'negative',
      });
      const store = useStore();
      store.$reset();
      void router.replace('/auth/login');
    }
    return value;
  },
  (error) => {
    Notify.create({
      message: '服务器发生错误，请稍后再试！',
      position: 'top',
      type: 'negative',
    });
    return Promise.reject(error);
  }
);

export default boot(({ app }) => {
  // for use inside Vue files (Options API) through this.$axios and this.$api

  app.config.globalProperties.$axios = axios;
  // ^ ^ ^ this will allow you to use this.$axios (for Vue Options API form)
  //       so you won't necessarily have to import axios in each vue file

  app.config.globalProperties.$api = api;
  // ^ ^ ^ this will allow you to use this.$api (for Vue Options API form)
  //       so you can easily perform requests against your app's API
});

export { api };
